<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
<head>
  <link href="https://gmpg.org/xfn/11" rel="profile">
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta name="generator" content="Hugo 0.68.3" />

  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>python常见的设计模式 &middot; 我的博客</title>
  <meta name="description" content="" />

  
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/print.css" media="print">
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/poole.css">
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/syntax.css">
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/hyde.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Abril+Fatface|PT+Sans:400,400i,700">


  
  <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/apple-touch-icon-144-precomposed.png">
  <link rel="shortcut icon" href="/favicon.png">

  
  
</head>

  <body class="theme-base-09 ">
  <aside class="sidebar">
  <div class="container sidebar-sticky">
    <div class="sidebar-about">
      <a href="/my_technology_blog/"><h1>我的博客</h1></a>
      <p class="lead">
       这里是任永刚的个人博客 
      </p>
    </div>

    <nav>
      <ul class="sidebar-nav">
        <li><a href="/my_technology_blog/">Home</a> </li>
        
      </ul>
    </nav>

    <p>&copy; 2020. All rights reserved. </p>
  </div>
</aside>

    <main class="content container">
    <div class="post">
  <h1>python常见的设计模式</h1>
  <time datetime=2020-04-21T00:00:00Z class="post-date">Tue, Apr 21, 2020</time>
  <h3 id="1单例模式只能创建一个对象">1，单例模式（只能创建一个对象）</h3>
<h3 id="1单例模式介绍">1、单例模式介绍</h3>
<pre><code>内容：保证一个类只有一个实例，并提供一个访问他的全局访问点
使用场景：当类只能有一个实例而且客户可以从一个总所周知的访问点访问他
例： 比如Test是一个类，你创建两个对象a=Test(), b=Test()在单例模式下a,b两个对象相同
优点：
1、 对唯一实例的受控访问（比如写日志时的日志句柄）
2、 单例模式相当于全局变量，单例模式防止了命名空间被污染
</code></pre>
<h3 id="-单例模式使用">· 单例模式使用</h3>
<pre><code>from abc import abstractmethod, ABCMeta

class Singleton(object):
    def __new__(cls, *args, **kwargs):           #new方法最后返回的是一个实例
        if not hasattr(cls, &quot;_instance&quot;):       #如果没有这个字段就调用父类创建
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance                     #永远返回的就是第一次创建的对象

class MyClass(Singleton):
    def __init__(self, name=None):
        if name:        #如果不传参数就不必赋值
            self.name = name
a = MyClass(&quot;a&quot;)        #第一次创建对象时传入的是&quot;a&quot;,所以a.name=a
print(a)
print(a.name)

b = MyClass('b')       #第二次创建对象时传入的是&quot;b&quot;，所以将name改成了b,所以b.name=b
print(b)
print(b.name)

print(a)                #在b创建实例化后name值已经改成了b所以 a.name=b
print(a.name)

# 注：可以看到实例a和b内存地址相同时一个实例
# &lt;__main__.MyClass object at 0x00FBACB0&gt;
# a
# &lt;__main__.MyClass object at 0x00FBACB0&gt;
# b
# &lt;__main__.MyClass object at 0x00FBACB0&gt;
# b
</code></pre>
<h3 id="2工厂模式">2，工厂模式</h3>
<pre><code>内容：不直接向客户端（创建的对象）暴露对象创建的细节，而是通过一个工厂类来负责创建各种类的实例
　　优点：
　　　　　　1、 隐藏了对象创建的实现细节
　　　　　　2、 客户端不需要修改代码
　　缺点：
　　　　　　1、 违反了单一职责原则，将创建逻辑集中到一个工厂类里
　　　　　　2、 当添加一个新产品时，需要修改工厂类代码，违法了开闭原则
</code></pre>
<h3 id="简单工厂模式">·简单工厂模式</h3>
<pre><code>from abc import abstractmethod, ABCMeta

class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self, money):
        pass

class Alipay(Payment):
    def __init__(self, enable_yuebao=False):
        self.enable_yuebao = enable_yuebao

    def pay(self, money):
        if self.enable_yuebao:
            print(&quot;余额宝支付%s元&quot; % money)
        else:
            print(&quot;支付宝支付%s元&quot; % money)

class ApplePay(Payment):
    def pay(self, money):
        print(&quot;苹果支付%s元&quot; % money)

#作用：用户在创建对象时不必关心需要传递那些参数
class PaymentFactory:
    def create_payment(self, method):
        if method == &quot;alipay&quot;:
            return Alipay()
        elif method == &quot;yuebao&quot;:
            return Alipay(True)
        elif method == &quot;applepay&quot;:
            return ApplePay()
        else:
            raise NameError(method)

f = PaymentFactory()
p = f.create_payment(&quot;alipay&quot;)    #创建一个Alipay对象，这里创建对象时不必关心需要传递那些参数
p.pay(100)
</code></pre>
<h3 id="3工厂方法模式">3，工厂方法模式</h3>
<pre><code>内容：定义一个用于创建对象的接口（工厂接口），让子类决定实例化那个参品类
　　角色：
　　　　　　1、 抽象工厂角色；
　　　　　　2、 具体工厂角色；
　　　　　　3、 抽象产品角色；
　　　　　　4、 具体产品角色；
　　　　　　特点：工厂方法模式相比简单工厂模式将每个具体参品都对应了一个具体工厂
　　适用场景：
　　　　　　1、 需要生产多种、大量复杂对象得时候
　　　　　　2、 需要降低耦合度的时候
　　　　　　3、 当系统中的参品类需要经常扩展的时候
　　优点：
　　　　　　1、 每个具体产品都对应一个具体工厂类，不需要修改工厂类代码
　　　　　　2、 隐藏了对象创建的实现细节
　　缺点：
　　　　　　每增加一个具体的产品类，就必须增加一个对应的具体工厂类
</code></pre>
<h3 id="工厂方法模式">工厂方法模式</h3>
<pre><code>from abc import abstractmethod, ABCMeta
class Payment(metaclass=ABCMeta):        #
    @abstractmethod
    def pay(self, money):
        pass
class Alipay(Payment):
    def pay(self, money):
        print(&quot;支付宝支付%s元&quot; % money)
class ApplePay(Payment):
    def pay(self, money):
        print(&quot;苹果支付%s元&quot;%money)

class PaymentFactory(metaclass=ABCMeta):
    @abstractmethod
    def create_payment(self):
        pass
class AlipayFactory(PaymentFactory):
    def create_payment(self):
        return Alipay()
class ApplePayFactory(PaymentFactory):
    def create_payment(self):
        return ApplePay()

af = AlipayFactory()
ali = af.create_payment()
ali.pay(120)
</code></pre>
<h3 id="4抽象工厂模式解决多类产品">4，抽象工厂模式（解决多类产品）</h3>
<pre><code>内容： 定义一个工厂接口，让工厂子类来创建一系列相关或相互依赖的对象
　　例： 生产一部手机，需要手机壳，CPU，操作系统三类对象进行组装，其中每类对象都有不同的种类。
　　　　 对每个具体工厂分别生产一部手机所需要的三个对象
　　特点：相比工厂方法模式，抽象工厂模式中的每个具体工厂都生产一套产品
　　适用场景： 强调一系类相关的产品对象得设计以便进行联合使用时
　　优点：
　　　　　　1、 将客户端与具体类的实现相分离
　　　　　　2、 每个工厂创建了一个完整的产品系列，使得易于交换产品系列
　　　　　　3、 有利于产品的一致性（即：产品间的约束关系）
　　缺点： 难以支持新种类的（抽象）产品
</code></pre>
<h3 id="抽象工厂">·抽象工厂</h3>
<pre><code>from abc import abstractmethod, ABCMeta

# ------抽象产品------
class PhoneShell(metaclass=ABCMeta):
    @abstractmethod
    def show_shell(self):
        pass

class CPU(metaclass=ABCMeta):
    @abstractmethod
    def show_cpu(self):
        pass

class OS(metaclass=ABCMeta):
    @abstractmethod
    def show_os(self):
        pass


# ------抽象工厂------
class PhoneFactory(metaclass=ABCMeta):
    @abstractmethod
    def make_shell(self):
        pass

    @abstractmethod
    def make_cpu(self):
        pass

    @abstractmethod
    def make_os(self):
        pass

# ------具体产品------
class SmallShell(PhoneShell):
    def show_shell(self):
        print(&quot;普通手机小手机壳&quot;)

class BigShell(PhoneShell):
    def show_shell(self):
        print(&quot;普通手机大手机壳&quot;)

class AppleShell(PhoneShell):
    def show_shell(self):
        print(&quot;苹果手机壳&quot;)

class SnapDragonCPU(CPU):
    def show_cpu(self):
        print(&quot;骁龙CPU&quot;)

class MediaTekCPU(CPU):
    def show_cpu(self):
        print(&quot;联发科CPU&quot;)

class AppleCPU(CPU):
    def show_cpu(self):
        print(&quot;苹果CPU&quot;)

class Android(OS):
    def show_os(self):
        print(&quot;Android系统&quot;)

class IOS(OS):
    def show_os(self):
        print(&quot;iOS系统&quot;)

# ------具体工厂------
class MiFactory(PhoneFactory):
    def make_cpu(self):
        return SnapDragonCPU()
    def make_os(self):
        return Android()
    def make_shell(self):
        return BigShell()

class HuaweiFactory(PhoneFactory):
    def make_cpu(self):
        return MediaTekCPU()
    def make_os(self):
        return Android()
    def make_shell(self):
        return SmallShell()

class IPhoneFactory(PhoneFactory):
    def make_cpu(self):
        return AppleCPU()
    def make_os(self):
        return IOS()
    def make_shell(self):
        return AppleShell()

# ------客户端------
class Phone:
    def __init__(self, cpu, os, shell):
        self.cpu = cpu
        self.os = os
        self.shell = shell

    def show_info(self):
        print(&quot;手机信息:&quot;)
        self.cpu.show_cpu()
        self.os.show_os()
        self.shell.show_shell()

def make_phone(factory):
    cpu = factory.make_cpu()
    os = factory.make_os()
    shell = factory.make_shell()
    return Phone(cpu, os, shell)

p1 = make_phone(IPhoneFactory())
p1.show_info()
</code></pre>

</div>


    </main>

    
      
    
  </body>
</html>
